package com.swim.common.utils;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @description : 生成id
 * @author      : 刘军武
 * @version     : 1.0  
 * @create      : 2019年12月6日 下午2:45:23
 **/
public class IDGenerator {
	
	public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f",
			"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
			"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
			"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
			"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
			"W", "X", "Y", "Z" };
 
	/**
	 * 生成无重复8位随机码（经测试，生成一千万个数据也没有出现重复）
	 * @return
	 */
	public static String generateShortUuid() {
	    StringBuffer shortBuffer = new StringBuffer();
	    String uuid = UUID.randomUUID().toString().replace("-", "");
	    for (int i = 0; i < 8; i++) {
	        String str = uuid.substring(i * 4, i * 4 + 4);
	        int x = Integer.parseInt(str, 16);
	        shortBuffer.append(chars[x % 0x3E]);
	    }
	    return shortBuffer.toString();
	 
	}
	
	/**
	 * 按时间戳生成id
	 * @return
	 */
	public static synchronized String getUid(){
		return new UID().randomUID();
	}
}

class UID{
	private static final String mask="yyyyMMddHHmmssSSS";
	private final DecimalFormat df= new DecimalFormat("0000");
	
	private static final long ONE_STEP =10000;
	private static final Lock LOCK = new ReentrantLock();
	private static long lastTime = System.currentTimeMillis();
	private static short lastCount=0;
	
	private static long time;
	private static short count;
	
	public UID(){
		LOCK.lock();
		try {
			if (lastCount == ONE_STEP) {
				boolean done = false;
				while(!done){
					long now = System.currentTimeMillis();
					if (now == lastTime) {
						Thread.sleep(1);
						continue;
					}else {
						lastTime = now;
						lastCount = 0;
						done = true;
					}
				}
			}
			time = lastTime;
			count = lastCount;
			
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			LOCK.unlock();
		}
	}
	
	protected String randomUID(){
		return time + df.format(count);
	}
	
	protected String randomTID(){
		return new SimpleDateFormat(mask).format(new Date(time));
	}
}
